% PDP
% pl: quadrato magico
% Francesco Cotto

%problema: queste regole non istanziano le variabili.
constraint_diff([]).
constraint_diff([H|T]) :- constraint_diff_aux(H,T),constraint_diff(T).

constraint_diff_aux(_, []).
constraint_diff_aux(E, [H|T]) :- E =\= H, constraint_diff_aux(E,T).

% --> all_different(L).


constraint_dom([]).
constraint_dom([H|T]) :- H >= 1, H =< 9, constraint_dom(T).

% --> X in 1..9.

%stesso problema: non istanzio, verifico solo dei valori...
constraint_val([X1,X2,X3,X4,X5,X6,X7,X8,X9]) :-
    V1 is X1+X2+X3, V1 =15,
    V2 is X4+X5+X6, V2 =15,
    V3 is X7+X8+X9, V3 =15,
    V4 is X1+X4+X7, V4 =15,
    V5 is X2+X5+X8, V5 =15,
    V6 is X3+X6+X9, V6 =15,
    V7 is X1+X5+X9, V7 =15,
    V8 is X3+X5+X7, V8 =15.
    
% --> X1+X2+X3 #= 15.

qm(L) :- constraint_dom(L),
         constraint_diff(L),
         constraint_val(L).
         
:- qm([2,7,6,9,5,1,4,3,8]).

% Soluzione con libreria: Constraint Logic Programmin Over Finit Domain.
:- use_module(library(clpfd)).
%X#>=1,X+Y#=3,X in 1..10,Y in 1..10,label([X,Y]).

clp_dom([]).
clp_dom([X|XS]) :- X in 1..9, clp_dom(XS).

clp_diff(XS) :- all_different(XS).

clp_val([X1,X2,X3,X4,X5,X6,X7,X8,X9]) :-
    X1+X2+X3#=15,
    X4+X5+X6#=15,
    X7+X8+X9#=15,
    X1+X4+X7#=15,
    X2+X5+X8#=15,
    X3+X6+X9#=15,
    X1+X5+X9#=15,
    X3+X5+X7#=15.


cerca :-
    clp_val(Vars),
    clp_dom(Vars),
    clp_diff(Vars),
    label(Vars),
    stampa_qm(Vars).

stampa_qm([X1,X2,X3,X4,X5,X6,X7,X8,X9]) :-
   writeln([X1,X2,X3]),
   writeln([X4,X5,X6]),
   writeln([X7,X8,X9]).
   